﻿using System;
using System.IO;
using System.Linq;
using System.Text;
using FFmpegVideoClip.Lib.AdvancedFragmentProcessor;
using FFmpegVideoClip.Mode.Files;
using UtilityToolsCollect.ObjectsLibrary.ProcessManage;

namespace FFmpegVideoClip.Lib.ClipGroups
{
    public class GropuMergeTaskFlow : TaskFlowAbstract
    {
        public readonly record struct InputInfo(TimeSpan Duration, string InFilePath);
        public int SourceClipIndex;
        private ProcessShell? m_ProcessShell;
        public GropuMergeTaskFlow(Clip clip, AdvancedParametersSchemeModule modules, int FragmentID, int sourceClipIndex)
        {
            ThisClip = clip;
            module = modules;

            ThisFragment = new Fragment
            {
                clip = ThisClip,
                Name = ThisClip.Name,
                Index = 0,
                ID = FragmentID,
                StartTimeValue = Tools.TimeZero,

                EndTimeValue = Tools.GetTimeSpanToString(clip.TimeDuration),
                InputPath = string.Empty,
                TempWritePath = string.Empty
            };

            successAndProgress = new SuccessAndProgress(module, ThisFragment);
            SourceClipIndex = sourceClipIndex;
        }

        public void Init()
        {
            if (disposedValue) return;
            StringBuilder sb = new();
            Clip SourceClip = ClipManage.ClipList.First(p => p.IndexUI == SourceClipIndex);

            if (!Directory.Exists(GroupMerge.TempCheckPath))
                Directory.CreateDirectory(GroupMerge.TempCheckPath);
            if (disposedValue) return;
            foreach (Fragment item in ThisClip!.Fragments)
            {
                if (!File.Exists(item.InputPath))
                    throw new FileNotFoundException($"合并异常：剪辑{item.clip!.Name}，的合并输入文件[{item.InputPath}]不存在");
                if (disposedValue) return;
                item.EndTimeValue = Tools.GetTimeSpanToString(GetMediaInfo.GetInfo(item.InputPath).Duration);
                sb.AppendLine($"file '{item.InputPath}'");
            }
            if (disposedValue) return;
            ParametersSign InputSign = module.GetInput();
            ThisFragment.InputPath = InputSign.Parameter = Path.Combine(GroupMerge.TempCheckPath, $"{ThisClip.Name}_Marge.txt");
            File.WriteAllText(InputSign.Parameter, sb.ToString());
            if (disposedValue) return;
            //处理输出
            ThisClip.FileWritePath = Path.Combine(ThisClip.OutDirectory, $"{ThisClip.Name}{Path.GetExtension(SourceClip.FileWritePath)}");
            ThisClip.FileWritePath = Tools.CheckDuplicateNameAndLegal(ThisClip.FileWritePath);
            SourceClip.FileWritePath = ThisClip.FileWritePath;
            module.GetOutput().Parameter = ThisClip.FileWritePath;
            if (disposedValue) return;
            ThisFragment.EndTimeValue = Tools.GetTimeSpanToString(ThisClip.TimeDuration);
            ThisFragment.TempWritePath = module.GetOutput().Parameter;

        }

        public override void Execute()
        {
            if (disposedValue) return;
            string InFileFullPath = module.GetInput().Parameter;
            string OutFileFullPath = module.GetOutput().Parameter;
            successAndProgress.Init();
            successAndProgress.WriteLineNewInfo($"剪辑[{ThisClip?.Name}]->流程[{module.SchemeName}]");
            if (string.IsNullOrEmpty(InFileFullPath) || !File.Exists(InFileFullPath))
            {
                successAndProgress.ErrorInfo = $"[{InFileFullPath}]输入文件不存在";
                successAndProgress.CompletedTimingSeconds = successAndProgress.TotalSeconds;
                LogManage.WriteLineNewInfo(successAndProgress.ErrorInfo, true);
                return;
            }
            if (string.IsNullOrEmpty(OutFileFullPath) || !Directory.Exists(Path.GetDirectoryName(OutFileFullPath)))
            {
                successAndProgress.ErrorInfo = $"[{OutFileFullPath}]输出路径不存在";
                successAndProgress.CompletedTimingSeconds = successAndProgress.TotalSeconds;
                LogManage.WriteLineNewInfo(successAndProgress.ErrorInfo, true);
                return;
            }
            if (disposedValue) return;
            if (File.Exists(OutFileFullPath))
                File.Delete(OutFileFullPath);
            if (disposedValue) return;
            string args = module.GenerateCommandArgument();
            successAndProgress.WriteLineNewInfo($"{module.ProcessorName} {args}");
            AdvancedTaskFlowManage.MergeInfo mi = new AdvancedTaskFlowManage.MergeInfo(successAndProgress);
            if (disposedValue) return;
            m_ProcessShell = new ProcessShell();
            m_ProcessShell.ExecuteWaitForExit(module.ProcessorName, args, mi.SetTaskInfo, mi.SetTaskInfo);
            if (disposedValue) return;
            successAndProgress.CompletedTimingSeconds = successAndProgress.TotalSeconds;
            successAndProgress.ReleaseScript();
            if (disposedValue) return;
            if (mi.IsError)
            {
                successAndProgress.ErrorInfo = $"处理错误:参数:[{module.ProcessorName}] [{args}]";
                throw new AdvancedTaskFlowManage.MergeException($"[{ThisClip!.Name}]合并执行异常:详情:\r\n{args}\r\n{{{mi}\r\n}}");
            }
            LogManage.WriteLineNewInfo(successAndProgress.Log);
            if (!successAndProgress.IsSuccess)
                throw new AdvancedTaskFlowManage.MergeException($"{successAndProgress.ErrorInfo} Log [{successAndProgress.Log}]");
        }

        protected override void OnDispose()
        {
            if (m_ProcessShell != null)
            {
                m_ProcessShell.Dispose();
                m_ProcessShell = null!;
            }
            base.OnDispose();
        }
    }
}
